package com.yand.data.map;


/**
 * 自己实现一个map
 * @param <K>
 * @param <V>
 */
public class YanDMap<K,V> {


    Node<K, V> [] first;

    int buttle = 16;

    public YanDMap(){
        this.first = new Node[buttle];
    }


    //往map中添加元素
     V put(K key, V value){

        int index = indexFor(hash(key));

        Node<K, V> node = first[index];
        Node<K, V> targetNode = new Node<K, V>(key, value);
        if(node == null){
            //

            first[index] = targetNode;
            return value;
        }else{
            Node old = null;

            while(node != null){

              if(hash(node.key) == hash(key) && key.equals(node.key)){
                node.setValue(value);
                return value;
              }
                old = node;
                node = node.getNext();
            }

            old.setNext(targetNode);
            return value;
        }
     }


     //获取元素
     //必须是hash 值一样且equals相等的情况下，才把值返回出来
     V get(K key){

        int index = indexFor(hash(key));

        Node<K, V> node = first[index];

        if(node == null){
            return null;
        }

        while(node != null){
            if(hash(node.getKey()) == hash(key) && node.getKey().equals(key)){
               return node.getValue();
            }

            node = node.getNext();
        }
        return null;

     }




























    private int hash(K key) {
        int h;
        return (key == null) ? 0 : Math.abs((h = key.hashCode())) ^ (h >>> buttle);
    }



    //算出位置
    private int indexFor(int hashCode){
        return hashCode % buttle;
    }


    //单链表
    class Node<K, V>{

        K key;

        V value;

        Node<K, V> next;

        public Node(K key, V value){
            this.key = key;
            this.value = value;
        }



        public void setNext(Node<K, V> next) {
            this.next = next;
        }


        public void setKey(K key) {
            this.key = key;
        }

        public void setValue(V value) {
            this.value = value;
        }


        public K getKey() {
            return key;
        }


        public V getValue() {
            return value;
        }

        public Node<K, V> getNext() {
            return next;
        }
    }






}
